package com.ylz.sjzx.sio.room.adapter;

import cn.hutool.core.collection.CollectionUtil;
import com.corundumstudio.socketio.SocketIOClient;
import com.ylz.sjzx.sio.common.core.enums.Cmd;
import com.ylz.sjzx.sio.common.core.utils.ExecutorPoolUtils;
import com.ylz.sjzx.sio.common.core.utils.GsonUtil;
import com.ylz.sjzx.sio.room.entity.LoginDelayItem;
import com.ylz.sjzx.sio.room.repository.SessionRepository;
import com.ylz.sjzx.sio.sdk.client.core.IMNioBase;
import com.ylz.sjzx.sio.sdk.client.session.IMSession;
import com.ylz.sjzx.sio.room.thread.LoginProcess;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.DelayQueue;

/**
 * 登录后的业务处理 延时队列使用原因：登录用户握手未完成
 *
 * @author wiqi
 * @version 1.0
 * @date 2021/1/4
 */
@Slf4j
public class LoginAfterService extends Thread {
    /**
     * 刚登录的等待握手延时业务处理
     */
    static DelayQueue<LoginDelayItem> loginDelayQueue = new DelayQueue<>();

    private Object objLock = new Object();

    public static void add(LoginDelayItem loginDelayItem) {
        loginDelayQueue.add(loginDelayItem);
    }

    @Override
    public void run() {
        while (IMNioBase.isGlobalRun) {
            try {
                List<LoginDelayItem> loginDelayList = new ArrayList();
                loginDelayQueue.drainTo(loginDelayList);
                if (CollectionUtil.isNotEmpty(loginDelayList)) {
                    for (LoginDelayItem loginDelayItem : loginDelayList) {
                        switch (loginDelayItem.getCmd()) {
                            case checklogin:
                                SocketIOClient socketIOClient =
                                        IMNioBase.getSocketIOClientMap().get(loginDelayItem.getSid());
                                if (socketIOClient != null) {
                                    Map mapCheckloginData =
                                            GsonUtil.json2Bean(GsonUtil.bean2Json(loginDelayItem.getOther()), Map.class);
                                    socketIOClient
                                            .sendEvent(Cmd.checklogin.getValue(), mapCheckloginData);
                                }
                                break;
                            case login:
                                IMSession imsession =
                                        IMNioBase.getGlobalSession().get(loginDelayItem.getSid());
                                //用户短线了吧
                                if (imsession == null || imsession.rightSocket() == null) {
                                    continue;
                                }
                                try {
                                    ExecutorPoolUtils.getLoginExecutor()
                                            .execute(() -> new LoginProcess(imsession).doRun());
                                } catch (Exception e) {
                                    log.error("LoginProcess 处理失败{}", imsession, e);
                                    //移除基础信息 防止处理登出业务
                                    SessionRepository.remove(imsession);

                                    imsession.getSocketIOClient().disconnect();
                                }
                                break;
                            default:
                                break;
                        }
                        log.debug("do login business{}", loginDelayItem);
                    }
                } else {
                    Thread.sleep(10);
                }
            } catch (Exception e) {
                log.error("永久线程处理登录业务异常{}", e);
            }

        }

    }

}
